<template>
	<view
		id="drag-button"
		class="drag-container"
		:class="{ transition: autoDocking && !moving }"
		:style="{
			left: `${left}px`,
			top: `${top}px`,
			width: `${size}rpx`,
			height: `${size}rpx`,
			zIndex: zIndex
		}"
		@touchend="touchend"
		@touchmove.stop.prevent="touchmove"
	>
		<slot />
	</view>
</template>

<script>
export default {
	name: 'DragButton',
	props: {
		/**
		 * 按钮大小
		 */
		size: {
			type: Number,
			default: 70
		},
		/**
		 * 层级
		 */
		zIndex: {
			type: Number,
			default: 999
		},
		/**
		 * x轴边界限制
		 */
		xEdge: {
			type: Number,
			default: 10
		},
		/**
		 * y轴边界限制
		 */
		yEdge: {
			type: Number,
			default: 90
		},
		/**
		 * 自动停靠
		 */
		autoDocking: {
			type: Boolean,
			default: true
		}
	},
	data() {
		return {
			top: 500,
			left: 300,
			width: 0,
			height: 0,
			moving: true
		};
	},
	mounted() {
		this.init();
	},
	methods: {
		init() {
			// 获取窗口尺寸
			const { windowWidth, windowHeight, windowTop } = uni.getSystemInfoSync();
			this._windowWidth = windowWidth;
			this._windowHeight = windowHeight;
			if (windowTop) {
				this._windowHeight += windowTop;
			}

			// 计算按钮初始位置
			const query = uni.createSelectorQuery().in(this);
			query
				.select('#drag-button')
				.boundingClientRect((data) => {
					if (!data) return;
					const { width, height } = data;
					this.width = width;
					this.height = height;
					this._offsetWidth = width / 2;
					this._offsetHeight = height / 2;
					this.left = this._windowWidth - this.width - this.xEdge;
					this.top = this._windowHeight - this.height - this.yEdge;
				})
				.exec();
		},

		// 拖动
		touchmove({ touches }) {
			if (touches.length !== 1) return false;

			this.moving = true;
			const { clientX, clientY } = touches[0];
			this.left = clientX - this._offsetWidth;

			let _clientY = clientY - this._offsetHeight;
			// #ifdef H5
			_clientY += this.height;
			// #endif
			this.top = _clientY;
		},

		// 松手
		touchend() {
			// 左右边界，松手自动停靠
			if (this.autoDocking) {
				const rigthEdge = this._windowWidth - this.width - this.xEdge;
				if (this.left < this._windowWidth / 2 - this._offsetWidth) {
					this.left = this.xEdge;
				} else {
					this.left = rigthEdge;
				}
			}

			// 上下边界
			const bottomEdge = this._windowHeight - this.height - this.yEdge;
			if (this.top < 50) {
				this.top = 50;
			} else if (this.top > bottomEdge) {
				this.top = bottomEdge;
			}

			this.moving = false;
		}
	}
};
</script>

<style lang="scss" scoped>
.drag-container {
	display: flex;
	justify-content: center;
	align-items: center;
	border-radius: 50%;
	position: fixed;
	// background-color: red;

	&.transition {
		transition: all 0.3s ease;
	}
}
</style>
